from threading import Condition


class Stack(object):
    def __init__(self):
        self._li = []

    def empty(self):
        return len(self._li) == 0

    def push(self, o):
        self._li.append(o)

    def pop(self):
        return self._li.pop(-1)

    def peek(self):
        return self._li[-1]

    def clear(self):
        self._li.clear()


class Queue(object):
    def __init__(self):
        self._li = []

    def enqueue(self, o):
        self._li.append(o)

    def dequeue(self):
        return self._li.pop(0)

    def empty(self):
        return len(self._li) == 0

    def peek(self):
        return self._li[0]

    def clear(self):
        self._li.clear()


class CountDownLatch:
    def __init__(self, count: int):
        if count <= 0:
            raise ValueError('count should larger than 0.')
        self._count = count
        self._cond = Condition()

    def wait(self):
        with self._cond:
            while self._count > 0:
                self._cond.wait()

    def count_down(self):
        with self._cond:
            self._count -= 1
            if self._count == 0:
                self._cond.notify_all()